<template>
    <el-card class="topContainerCard">
        <div style="display: flex; justify-content: space-between">
            <span>表单名称：{{formName}}</span>
            <div>
                <div v-if="checkIsCanSave" style="display: inline-block;width: 240px; height: 30px; background-color: rgba(238,183,5,0.56);margin-right: 20px; text-align: center">
                    <span style="color: rgba(248,143,6,0.98); line-height: 30px">
                        历史版本只可查看，不可修改
                    </span>
                </div>
                <el-select v-model="currentVersion" placeholder="版本" style="width: 200px;margin-right: 10px" @change="selectChange()" v-loading.fullscreen.lock="fullscreenLoading">
                    <el-option
                        v-for="item in currentFormVersionList"
                        :key="item.version"
                        :label="item.innerName"
                        :value="item.version"
                    />
                </el-select>
                <el-button @click="closeCurrentPage()">关闭</el-button>
                <el-button type="primary" :loading="saveFormJsonLoading" :disabled="checkIsCanSave" @click="saveFormJsonInfo()">保存</el-button>
            </div>
        </div>
    </el-card>

    <div class="allContainer">
        <div>
            <el-card :style="'width:' + leftWidth + 'px;' + 'height:' + height + 'px'">
                <div class="cardContainerDiv" :style="'height:' + (height - 40) + 'px'">
                    <el-divider>全局设置</el-divider>
                    <el-form :model="globalProperties" style="margin-bottom: 70px">
                        <el-form-item label="所属微服务" label-width="20%" prop="applicationName">
                            <el-radio-group v-model="globalProperties.colNum">
                                <el-radio :label="1">单列</el-radio>
                                <el-radio :label="2">双列</el-radio>
                                <el-radio :label="3">三列</el-radio>
                            </el-radio-group>
                        </el-form-item>
                    </el-form>

                    <el-divider>表单组件</el-divider>

                    <div>
                        <draggable
                            :list="formComponentList"
                            ghost-class="ghostClass"
                            chosen-class="chosenClass"
                            animation="300"
                            :force-fallback="true"
                            :sort="false"
                            :group="{name:'lowcode',pull:'clone',put:false}"
                            @start="onStart"
                            :clone="cloneDefaultField"
                            item-key="sourceId"
                        >
                            <template #item="{ element }">
                                <div class="componentListItemClass">
                                    {{ element.name }}
                                </div>
                            </template>
                        </draggable>
                    </div>
                </div>
            </el-card>
        </div>

        <div>
            <el-card :style="'width:' + rightWidth + 'px;' + 'height:' + height + 'px'">
                <div class="cardContainerDiv" :style="'height:' + (height - 40) + 'px'">
                    <el-divider>预览</el-divider>
                    <el-form label-width="10%" :style="formCols">
                        <el-form-item v-for="(item, index) in formBuildList" :label="item.labelName">
                            <component :is="item.component" :isEdit="false" :properties="item"/>
                        </el-form-item>
                    </el-form>
                    <div class="formSubmitButton">
                        <el-button>取消</el-button>
                        <el-button type="primary">提交</el-button>
                    </div>
                    <el-divider style="margin-top: 60px">构建</el-divider>
                    <div class="draggableContainer">
                        <el-form>
                            <draggable :list="formBuildList"
                                       animation="300"
                                       :force-fallback="true"
                                       :group="{name:'lowcode'}"
                                       item-key="id"
                            >
                                <template #item="{ element }">
                                    <el-form-item class="itemClass" :label="element.labelName" label-width="10%">
                                        <component :is="element.component" :isEdit="true" :properties="element" @click.stop="showComponentDrawer(element)"/>
                                        <component is="CloseCircleOutlined" class="closeClass" @click.stop="deleteComponent(element)"/>
                                    </el-form-item>
                                </template>
                            </draggable>
                        </el-form>

                    </div>
                </div>
            </el-card>
        </div>

        <div>
            <el-drawer
                v-model="isShowDrawer"
                :title="currentDrawerTitle"
                :lock-scroll="true"
                :close-on-click-modal="false"
            >
                <div>
                    <component :is="currentDrawer" :properties="currentPropertiesCopy"/>
                </div>
                <template #footer>
                    <div style="flex: auto">
                        <el-button @click="cancelClick">取消</el-button>
                        <el-button type="primary" @click="confirmClick">确认</el-button>
                    </div>
                </template>
            </el-drawer>
        </div>
    </div>
</template>

<script>
import draggable from "vuedraggable";
import {deepCopy} from "@/utils/tagCreate";
import {componentList} from "@/views/bpmn/form/formComponent";
import YwuFormInput from "@/views/bpmn/form/component/YwuFormInput";
import YwuFormInputDrawer from "@/views/bpmn/form/drawer/YwuFormInputDrawer";
import {queryFormEntity, queryVersionInfo, queryVersionList, updateFormJsonInfo} from "@/request/flow";
import {ElNotification} from "element-plus";

export default {
    name: "BuildForm",
    components: {
        draggable,
        YwuFormInput,
        YwuFormInputDrawer
    },
    data() {
        return {
            leftWidth: 0,
            rightWidth: 0,
            height: 0,
            formList: [],
            globalProperties: {
                colNum: 1
            },
            formComponentList: [],
            formBuildList: [],
            isShowDrawer: false,
            currentDrawerTitle: "",
            currentDrawer: "",
            currentPropertiesCopy: {},
            currentElementId: "",
            saveFormJsonLoading: false,
            currentFormVersionList: [],
            formName: "",
            currentVersion: 0,
            fullscreenLoading: false
        }
    },
    methods: {
        calcWidthAndHeight() {
            let windowWidth = window.innerWidth;
            let windowHeight = window.innerHeight;
            if (windowHeight < 500) {
                this.height = 400;
            } else {
                this.height = windowHeight - 100;
            }
            if (windowWidth < 1000) {
                this.leftWidth = 200 - 15;
                this.rightWidth = 800;
            } else {
                this.leftWidth = windowWidth / 5 - 15;
                this.rightWidth = windowWidth - windowWidth / 5;
            }
        },
        cloneDefaultField(e) {
            return deepCopy(e);
        },
        onStart(e) {
            e.item._underlying_vm_.id = this.generateUUID();
        },
        randomNumber() {
            return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
        },
        generateUUID() {
            return (this.randomNumber() + this.randomNumber() + "-" + this.randomNumber() + "-" + this.randomNumber() +
                "-" + this.randomNumber() + "-" + this.randomNumber() + this.randomNumber() + this.randomNumber());
        },
        showComponentDrawer(element) {
            this.currentElementId = element.id
            this.currentDrawerTitle = element.drawerTitle;
            this.currentDrawer = element.drawer;
            this.currentPropertiesCopy = {...element};
            this.isShowDrawer = true;
        },
        cancelClick() {
            this.currentElementId = "";
            this.currentDrawerTitle = "";
            this.currentDrawer = "";
            this.currentPropertiesCopy = {};
            this.isShowDrawer = false;
        },
        confirmClick() {
            let index = -1;
            // 遍历当前列表，删除元素ID对应的数据
            for (let i = 0; i < this.formBuildList.length; i++) {
                if (this.formBuildList[i].id === this.currentElementId) {
                    index = i;
                }
            }
            if (index >= 0) {
                this.formBuildList[index] = {...this.currentPropertiesCopy};
            }
            // 将备份的数据填充到原始数据对象中
            this.currentElementId = "";
            this.currentDrawerTitle = "";
            this.currentDrawer = "";
            this.currentPropertiesCopy = {};
            this.isShowDrawer = false;
        },
        deleteComponent(element) {
            let index = -1;
            // 遍历当前列表，删除元素ID对应的数据
            for (let i = 0; i < this.formBuildList.length; i++) {
                if (this.formBuildList[i].id === element.id) {
                    index = i;
                }
            }
            if (index >= 0) {
                this.formBuildList.splice(index, 1);
            }
        },
        closeCurrentPage() {
            window.close();
        },
        saveFormJsonInfo() {
            this.saveFormJsonLoading = true;
            let currentQueryParams = this.$route.query;
            // 构建json
            let jsonInfo = {
                globalProperties: this.globalProperties,
                componentJson: this.formBuildList
            }
            // 序列化字符串
            let jsonStr = JSON.stringify(jsonInfo)
            let param = {
                id: currentQueryParams.id,
                formJson: jsonStr
            }
            updateFormJsonInfo(param).then(res => {
                if (res.code === "200") {
                    this.saveFormJsonLoading = false;
                    ElNotification({
                        title: 'Success',
                        message: res.message,
                        type: 'success'
                    })
                    // 延迟一秒关闭页面
                    setTimeout(() => {
                        window.close();
                    }, 1000);
                }
            })
        },
        selectChange() {
            this.fullscreenLoading = true
            let currentQueryParams = this.$route.query;
            this.$router.replace({
                path: this.$route.path,
                query: {
                    id: currentQueryParams.id,
                    version: this.currentVersion
                }
            })
            queryVersionInfo({resourceId: currentQueryParams.id, version: this.currentVersion}).then(res => {
                let formJson = res.data.formJson
                // 序列化json
                let jsonInfo = JSON.parse(formJson);
                this.globalProperties = jsonInfo.globalProperties
                this.formBuildList = jsonInfo.componentJson
                this.formName = res.data.nameCn + " -- " + res.data.nameEn;
                this.fullscreenLoading = false
            }).catch(res => {
                this.fullscreenLoading = false
            })
        }
    },
    computed: {
        formCols() {
            let res = "display: grid;gap: 16px;"
            let repeat = `grid-template-columns: repeat(${this.globalProperties.colNum}, 1fr);`
            return res + repeat;
        },
        checkIsCanSave() {
            if (this.currentFormVersionList && this.currentFormVersionList.length > 0) {
                // 如果当前表单存在草稿版本，那么只有草稿版本可以编辑，其他版本都不可以编辑
                if (this.currentFormVersionList[0].version === 0) {
                    return this.currentVersion !== 0;
                }
                // 如果当前表单不存在草稿版本，那么只有最新版本可以编辑，其他版本都不可以编辑
                return this.currentFormVersionList[0].version !== this.currentVersion;
            } else {
                return true;
            }
        }
    },
    mounted() {
        this.$nextTick(() => {
            this.calcWidthAndHeight();
        });
        // 在组件挂载时添加窗口大小改变的监听器
        window.addEventListener('resize', this.calcWidthAndHeight);
        // 配置可拖拽的组件列表
        this.formComponentList = componentList;
        // 查询当前表单的详情
        let currentQueryParams = this.$route.query;
        this.fullscreenLoading = true
        // 查询版本列表
        queryVersionList({id: currentQueryParams.id}).then(res => {
            if (res.code === '200') {
                this.currentFormVersionList = res.data;
                if (this.currentFormVersionList.length === 0) {
                    // 没有历史版本，说明是草稿状态的表单，则查表单原始数据
                    queryFormEntity({id: currentQueryParams.id}).then(res => {
                        let formJson = res.data.formJson
                        // 序列化json
                        let jsonInfo = JSON.parse(formJson);
                        this.globalProperties = jsonInfo.globalProperties
                        this.formBuildList = jsonInfo.componentJson
                        this.formName = res.data.nameCn + " -- " + res.data.nameEn;
                        // 手动添加一个草稿版本的状态
                        this.currentFormVersionList.push({
                            innerName: "草稿版本",
                            version: 0
                        })
                        this.currentVersion = 0;
                        this.fullscreenLoading = false
                    }).catch(res => {
                        this.fullscreenLoading = false
                    })
                    return;
                }
                for (let index = 0; index < this.currentFormVersionList.length; index++) {
                    let tempInfo = this.currentFormVersionList[index];
                    if (tempInfo.version === 0) {
                        tempInfo.innerName = "草稿版本";
                    } else {
                        tempInfo.innerName = "版本" + tempInfo.version;
                    }
                }
                // 判断当前请求url中是否携带了version版本，如果携带了，则查询对应版本的数据，如果没带，则默认查询最新版本（有草稿则查草稿版本）
                if (currentQueryParams.version !== null && currentQueryParams.version !== undefined) {
                    queryVersionInfo({resourceId: currentQueryParams.id, version: currentQueryParams.version}).then(res => {
                        let formJson = res.data.formJson
                        // 序列化json
                        let jsonInfo = JSON.parse(formJson);
                        this.globalProperties = jsonInfo.globalProperties
                        this.formBuildList = jsonInfo.componentJson
                        this.formName = res.data.nameCn + " -- " + res.data.nameEn;
                        this.currentVersion = parseInt(currentQueryParams.version);
                    })
                } else {
                    queryVersionInfo({resourceId: currentQueryParams.id, version: this.currentFormVersionList[0].version}).then(res => {
                        let formJson = res.data.formJson
                        // 序列化json
                        let jsonInfo = JSON.parse(formJson);
                        this.globalProperties = jsonInfo.globalProperties
                        this.formBuildList = jsonInfo.componentJson
                        this.formName = res.data.nameCn + " -- " + res.data.nameEn;
                        this.currentVersion = this.currentFormVersionList[0].version;
                    })
                }
            }
            this.fullscreenLoading = false
        }).catch(res => {
            this.fullscreenLoading = false
        })
    },
    beforeDestroy() {
        // 在组件销毁前移除监听器，避免内存泄漏
        window.removeEventListener('resize', this.calcWidthAndHeight);
    }
}
</script>

<style scoped lang="less">
.componentListItemClass {
    font-size: 13px;
    color: #606266;
    text-align: center;
    width: 90%;
    line-height: 250%;
    margin-left: 5%;
    //去除光标
    caret-color: transparent;
    background-color: #FAFCFF;
    transition: box-shadow 0.3s ease;
    border: 1px solid #F0F2F5;
    border-radius: 5px;
}
.componentListItemClass:hover{
    cursor: pointer;
    color: #409EFF;
    background-color: #EBEEF5;
}

.topContainerCard {
    height: 68px;
    margin-top: 6px;
    margin-bottom: 6px;
}

.allContainer {
    display: flex;
    justify-content: space-between;
    // 界面禁止选中
    -webkit-user-select: none; /* Safari */
    -moz-user-select: none; /* Firefox */
    -ms-user-select: none; /* IE10+ */
    user-select: none; /* Standard syntax */
}

.cardContainerDiv {
    overflow-y: auto;
}

.formSubmitButton {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* 自定义整个滚动条 */
.cardContainerDiv::-webkit-scrollbar {
    width: 8px; /* 设置滚动条的宽度 */
}

/* 自定义滚动条轨道 */
.cardContainerDiv::-webkit-scrollbar-track {
    background: #f1f1f1; /* 设置轨道的背景颜色 */
}

/* 自定义滚动条的滑块（thumb） */
.cardContainerDiv::-webkit-scrollbar-thumb {
    background: #b7b7b7; /* 设置滑块的背景颜色 */
    border-radius: 20px;
}

/* 当滑块悬停或活动时的样式 */
.cardContainerDiv::-webkit-scrollbar-thumb:hover {
    background: #a9a9a9; /* 设置滑块在悬停状态下的背景颜色 */
}

.draggableContainer {
    width: 98%;
    //去除光标
    caret-color: transparent;
    .itemClass {
        position: relative;
        transition: box-shadow 0.3s ease;
        margin-bottom: 0.3%;
        .closeClass {
            display: none;
        }
    }
    .itemClass:hover {
        cursor: pointer;
        box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.5);
        .closeClass {
            position: absolute;
            color: #e76565;
            top: 2px;
            right: 2px;
            display: block;
        }
    }
}
.draggableContainer:hover {
    cursor: pointer;
}

</style>